﻿using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Duo1JHttpServer.Framework.Model;
using Duo1JHttpServer.Framework.Utils;

namespace Duo1JHttpServer.Framework.Server
{
    /// <summary>
    /// 抽象http服务器类
    /// </summary>
    internal sealed class WebServer
    {
        /// <summary>
        /// 服务器ip地址
        /// </summary>
        private readonly string ipAddress;

        /// <summary>
        /// 服务器端口
        /// </summary>
        private readonly int port;

        private TcpListener listener;

        private bool isActive = true;

        /// <param name="ipAddress">服务器ip地址</param>
        /// <param name="port">服务器端口</param>
        public WebServer(string ipAddress, int port)
        {
            this.ipAddress = ipAddress;
            this.port = port;
        }

        /// <summary>
        /// 开始监听
        /// </summary>
        public void Listen()
        {
            ConsoleUtils.WriteColorLine($"Start listen => {ipAddress}:{port}", ConsoleColor.Magenta);
            listener = new TcpListener(IPAddress.Parse(ipAddress), port);
            listener.Start();

            while (isActive && WebMain.running)
            {
                TcpClient client = null;
                try
                {
                    client = listener.AcceptTcpClient();
                    new Thread(new ThreadStart(new HttpPreProcessor(client, this).Process)).Start();
                    Thread.Sleep(1);
                }
                catch (Exception e)
                {
                    if (client != null)
                    {
                        StaticHandler.RequestServerError(new StreamWriter(new BufferedStream(client.GetStream())),
                            $"{e.Message}\n{e.StackTrace}");
                        continue;
                    }
                }
            }
        }

        /// <summary>
        /// 处理GET请求
        /// </summary>
        /// <param name="model">http请求模型</param>
        public void HandleGETRequest(RequestModel model)
        {
            RequestDispatcher.Dispatch(model);
        }

        /// <summary>
        /// 处理POST请求
        /// </summary>
        /// <param name="model">http请求模型</param>
        /// <param name="inputData">请求数据流</param>
        public void HandlerPOSTRequest(RequestModel model, StreamReader inputData)
        {
            try
            {
                RequestDispatcher.Dispatch(model);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            finally
            {
                inputData?.Close();
            }
        }

        /// <summary>
        /// 关闭服务器
        /// </summary>
        public void Close()
        {
            isActive = false;
            listener.Stop();
        }
    }
}